package com.mia.craftstudio;

import com.google.common.collect.BiMap;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Multimap;
import com.google.gson.JsonElement;
import com.mia.craftstudio.api.ICSProject;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public class CSProject implements ICSProject {
   private static HashMap projectsList = new HashMap();
   private final List packs = new ArrayList();
   private final List jsons = new ArrayList();
   private final Map models = new HashMap();
   private final Map animations = new HashMap();
   private final Map descriptors = new HashMap();
   private final Multimap modelsMM = HashMultimap.create();
   private final String projectName;
   private final String projectContainer;
   private final String projectID;
   private final String projectAssetPath;
   private final File jarFile;

   public CSProject(String name, String container, String assetPath, File jarFile) {
      this.projectID = String.format("%s:%s", container, name);
      if (projectsList.containsKey(this.projectID)) {
         throw new CSExceptions.DuplicateProjectException(this.projectID);
      } else {
         projectsList.put(this.projectID, this);
         this.projectName = name;
         this.projectContainer = container;
         this.projectAssetPath = assetPath;
         this.jarFile = jarFile;
      }
   }

   public static ICSProject getProjectFromID(String projectID) {
      return (ICSProject)projectsList.get(projectID);
   }

   public String getName() {
      return this.projectName;
   }

   public String getContainerName() {
      return this.projectContainer;
   }

   public String getProjectID() {
      return this.projectID;
   }

   public File getJarFile() {
      return this.jarFile;
   }

   public String getProjectAssetPath() {
      return this.projectAssetPath;
   }

   public String toString() {
      return this.jarFile != null ? String.format("CSProject[%s] located in File: %s", this.projectID, this.jarFile.toString()) : String.format("CSProject[%s]", this.projectID);
   }

   private Set getResourceList(String path) throws CSExceptions.ResourcesNotFoundException {
      HashSet filenames = new HashSet();

      try {
         URL directory = CSProject.class.getResource(path);
         if (directory != null && "file".equals(directory.getProtocol())) {
            filenames.addAll(Arrays.asList((new File(directory.toURI())).list()));
         } else {
            if (this.jarFile == null || !this.jarFile.isFile()) {
               throw new CSExceptions.ResourcesNotFoundException(this);
            }

            path = path.substring(1) + "/";
            ZipFile zipfile = new ZipFile(this.jarFile);
            Enumeration entryList = zipfile.entries();

            while(entryList.hasMoreElements()) {
               ZipEntry zipEntry = (ZipEntry)entryList.nextElement();
               if (!zipEntry.getName().equals(path) && zipEntry.getName().startsWith(path)) {
                  filenames.add(zipEntry.getName().substring(path.length()));
               }
            }

            zipfile.close();
         }
      } catch (URISyntaxException var7) {
         var7.printStackTrace();
      } catch (IOException var8) {
         var8.printStackTrace();
      } catch (CSExceptions.ResourcesNotFoundException var9) {
         throw var9;
      }

      return filenames;
   }

   public ICSProject addAllPacks(IPackReaderCallback callback) {
      this.packs.clear();
      List orderedPacks = null;
      orderedPacks = new ArrayList(this.getResourceList(this.projectAssetPath));
      CraftStudioLib.debug(String.format("Looking up CSPacks for %s, unordered list", this));
      Iterator var3 = orderedPacks.iterator();

      String pack;
      while(var3.hasNext()) {
         pack = (String)var3.next();
         CraftStudioLib.debug(String.format("\t+ %s", pack));
      }

      Collections.sort(orderedPacks, new Comparator<String>() {
         private boolean isIntNumber(String str) {
            char[] var2 = str.toCharArray();
            int var3 = var2.length;

            for(int var4 = 0; var4 < var3; ++var4) {
               char c = var2[var4];
               if (!Character.isDigit(c)) {
                  return false;
               }
            }

            return true;
         }

         public int compare(String name1, String name2) {
            try {
               int sep1 = name1.indexOf(95);
               int sep2 = name2.indexOf(95);
               String date1 = name1.substring(0, sep1);
               String date2 = name2.substring(0, sep2);
               if (this.isIntNumber(date1)) {
                  if (this.isIntNumber(date2)) {
                     int result = Long.valueOf(date1).compareTo(Long.valueOf(date2));
                     if (result == 0) {
                        return name1.substring(sep1).toLowerCase(Locale.US).compareTo(name2.substring(sep2).toLowerCase(Locale.US));
                     }

                     return result;
                  }

                  return 1;
               }

               if (this.isIntNumber(date2)) {
                  return -1;
               }
            } catch (Exception var8) {
            }

            return name1.toLowerCase(Locale.US).compareTo(name2.toLowerCase(Locale.US));
         }
      });
      CraftStudioLib.debug(String.format("Loading CSPacks for %s, ordered list: ", this));
      var3 = orderedPacks.iterator();

      while(var3.hasNext()) {
         pack = (String)var3.next();
         CraftStudioLib.debug(String.format("\t+ %s", pack));
         if (pack.endsWith(".cspack")) {
            this.addPack(new CSPack(pack, callback));
         }

         if (pack.endsWith(".json")) {
            this.jsons.add(pack);
         }
      }

      return this;
   }

   public ICSProject addPack(CSPack pack) {
      this.packs.add(pack);
      pack.project = this;
      return this;
   }

   public boolean removePack(String name) {
      Iterator var2 = this.packs.iterator();

      CSPack pack;
      do {
         if (!var2.hasNext()) {
            return false;
         }

         pack = (CSPack)var2.next();
      } while(!pack.getName().equals(name));

      this.packs.remove(pack.cleanup());
      return true;
   }

   public List getPacks() {
      return this.packs;
   }

   public ICSProject loadPacks(InputStream overrideStream) {
      this.models.clear();
      this.modelsMM.clear();
      this.animations.clear();
      CSPack[] var2 = (CSPack[])Arrays.copyOf(this.packs.toArray(new CSPack[0]), this.packs.size());
      int var3 = var2.length;

      for(int var4 = 0; var4 < var3; ++var4) {
         CSPack pack = var2[var4];

         try {
            pack.readPackFile(overrideStream);
         } catch (CSExceptions.NoCSProjectException var7) {
            System.out.printf("Removing CSPack '%s' from CSProject '%s'. It was improperly added.", pack.getName(), this.projectName);
            this.packs.remove(pack.cleanup());
         }
      }

      Iterator var8 = this.packs.iterator();

      while(var8.hasNext()) {
         CSPack pack = (CSPack)var8.next();
         BiMap entries = pack.getEntries();
         Iterator var11 = entries.values().iterator();

         while(var11.hasNext()) {
            CSPack.ProjectEntry entry = (CSPack.ProjectEntry)var11.next();
            if (entry.getType() == 0) {
               this.modelsMM.put(entry.getName(), this.models.get(entry.getID()));
            }
         }
      }

      CraftStudioLib.debug(String.format("%s", this));
      CraftStudioLib.debug(String.format("\t+ %d models", this.models.size()));
      CraftStudioLib.debug(String.format("\t+ %d animations", this.animations.size()));
      return this;
   }

   public Integer findFirstIDfromName(String name) {
      List ret = this.getIDsForName(name);
      return ret.size() > 0 ? (Integer)ret.get(0) : -1;
   }

   public List getIDsForName(String name) {
      ArrayList ret = new ArrayList();
      Iterator var3 = this.packs.iterator();

      while(var3.hasNext()) {
         CSPack pack = (CSPack)var3.next();
         BiMap entries = pack.getEntries();
         Iterator var6 = entries.values().iterator();

         while(var6.hasNext()) {
            CSPack.ProjectEntry entry = (CSPack.ProjectEntry)var6.next();
            if (entry.getName().equals(name)) {
               ret.add(entries.inverse().get(entry));
            }
         }
      }

      return ret;
   }

   public String findNamefromID(Integer id) {
      Iterator var2 = this.packs.iterator();

      BiMap entries;
      do {
         if (!var2.hasNext()) {
            return null;
         }

         CSPack pack = (CSPack)var2.next();
         entries = pack.getEntries();
      } while(!entries.containsKey(id));

      return ((CSPack.ProjectEntry)entries.get(id)).getName();
   }

   public BiMap getModels() {
      return ImmutableBiMap.copyOf(this.models);
   }

   public List getModels(String name) {
      return (List)(this.modelsMM.get(name).size() > 0 ? ImmutableList.copyOf(this.modelsMM.get(name)) : new ArrayList());
   }

   public CSModel getModel(Integer id) {
      return (CSModel)this.models.get(id);
   }

   public CSModel getModel(String name) {
      return this.modelsMM.get(name).size() > 0 ? (CSModel)this.getModels(name).get(0) : null;
   }

   public int getModelCount() {
      return this.models.size();
   }

   public Map getAnimations() {
      return ImmutableMap.copyOf(this.animations);
   }

   public CSModelAnim getAnimation(Integer id) {
      return (CSModelAnim)this.animations.get(id);
   }

   public int getAnimationCount() {
      return this.animations.size();
   }

   public JsonElement getDescriptor(Integer id) {
      return (JsonElement)this.descriptors.get(id);
   }

   boolean addModel(Integer id, CSModel model) {
      return this.models.put(id, model) != null;
   }

   boolean addAnimation(Integer id, CSModelAnim anim) {
      return this.animations.put(id, anim) != null;
   }

   boolean addDescriptor(Integer id, JsonElement json) {
      return this.descriptors.put(id, json) != null;
   }
}
